﻿var DrawingArea = function (options) {
	this.map = options.map;
	this.style = options.editorStyle;
	this.isAdding = false;
	this.isDrawing = false;
	this.eventListeners = { };

	this.stVert = null;

	this.areaObj = {
		areaPoly: this.createPolygon(),
		borderLine: this.style.enableBorder ? this.createPolyline() : null,
		dottedLine: this.style.enableDotted ? this.createDottedLine() : null,
		markerList: this.style.enableMarkers ? [] : null
	};

	this.setMapCursor('default');

	var self = this;

	//var eventAction = null;

	// подписаться на событие
	this.subscribe = function(eventType, eventHandler) {
		switch (event) {
		case "end_drawing":
			{
				this.actionEndDrawing = eventHandler;
				break;
			}
		}
		self.actionEndDrawing = eventHandler;
	};

	//выполнение события
	this.fire = function(event) {
		var eventAction = null;
		switch (event) {
		case "end_drawing":
			{
				eventAction = this.actionEndDrawing;
				break;
			}
		}
		if (eventAction != null) {
			eventAction();
		}
	};


	var LatLng = function(lat, lng) {
		this.X = lat;
		this.Y = lng;
	};

	this.LatLng = LatLng;

	LatLng.prototype.lat = function() {
		return this.X;
	};
	LatLng.prototype.lng = function() {
		return this.Y;
	};


	var Marker = function(map) {
		this.mountMap = map;
		var marker = new google.maps.Marker({
			//animation: google.maps.Animation.DROP,
			draggable: false
		});
		this.marker = marker;
		var self = this;
		google.maps.event.addListener(this.marker, 'click', function() {
			if (self.marker.info) {
				self.marker.info.open(self.mountMap, self.marker);
			}
			;
		});
	};

	this.Marker = Marker;

	Marker.prototype.setPosition = function(latlng) {
		this.marker.setPosition(new google.maps.LatLng(latlng.X, latlng.Y));
	};
	Marker.prototype.setCenterPosition = function (latlng) {
		this.marker.setPosition(new google.maps.LatLng(latlng.X, latlng.Y));
		this.mountMap.setCenter(new google.maps.LatLng(latlng.X, latlng.Y));
	};
	Marker.prototype.setInfoContent = function(contentHtml) {
		this.marker.info.setContent(contentHtml);
	};
	Marker.prototype.hideMarker = function() {
		this.marker.setMap(null);
	};
	Marker.prototype.setIcon = function(figure) {
		this.marker.setIcon(figure.icon);
		this.marker.setShadow(figure.shadow);
	};
	Marker.prototype.placeSimpleMarker = function(latlng) {
		delete this.marker.info;
		this.marker.setMap(this.mountMap);
		this.setPosition(latlng);
	};
	Marker.prototype.placeCenterMarker = function(latlng) {
		this.placeSimpleMarker(latlng);
		this.mountMap.setCenter(new google.maps.LatLng(latlng.X, latlng.Y));
	};
	Marker.prototype.placeInfoMarker = function(latlng, infoContent) {
		this.placeSimpleMarker(latlng);
		this.marker.info = new google.maps.InfoWindow({
			content: infoContent
		});
	};
	Marker.prototype.placeCenterInfoMarker = function(latlng, infoContent) {
		this.placeCenterMarker(latlng);
		this.marker.info = new google.maps.InfoWindow({
			content: infoContent
		});
	};

	var Area = function(map) {
		this.mountMap = map;
		this.polygon = new google.maps.Polygon({
			map: map,
			strokeColor: "00FF00",
			strokeWeight: 2,
			strokeOpacity: 0.8,
			editable: false,
			fillColor: "00FF00",
			zIndex: 10,
		});
	};

	this.Area = Area;

	Area.prototype.placeArea = function(path) {
		this.polygon.setPath(path);
		this.polygon.setMap(this.mountMap);
	};

	Area.prototype.hideArea = function() {
		this.polygon.setPath([]);
		this.polygon.setMap(null);
	};
	



	/*
	google.maps.event.addListener(this.areaObj.areaPoly, 'mouseover', function (mouseEvent) {
	if (!self.isDrawing) { 
		self.areaObj.areaPoly.setOptions({ editable: true });
	}
	});
	google.maps.event.addListener(this.areaObj.areaPoly, 'mouseout', function (mouseEvent) {
	if (!self.isDrawing) { 
		self.areaObj.areaPoly.setOptions({ editable: false });
	}
	});
	/*
	this.delete = false;
	this.areaVertClick = false;
	google.maps.event.addListener(this.areaObj.areaPoly, 'mousedown', function (mouseEvent) {
		if (!self.isDrawing && (mouseEvent.vertex != undefined)) {
			//self.delete = true;
			self.areaVertClick = true;
		}
	});
	google.maps.event.addListener(this.areaObj.areaPoly, 'mousemove', function (mouseEvent) {
		if (!self.isDrawing && self.areaVertClick == true) {
			//self.delete = false;
			var path = self.areaObj.areaPoly.getPath();
			path.removeAt(mouseEvent.vertex);
			path.insertAt(mouseEvent.vertex, mouseEvent.latLng);
		}
	});
	google.maps.event.addListener(this.areaObj.areaPoly, 'mouseup', function (mouseEvent) {
		if (!self.isDrawing && mouseEvent.vertex != undefined) {
			if (self.delete == true) {
				var path = self.areaObj.areaPoly.getPath();
				path.removeAt(mouseEvent.vertex);
			}
			self.delete = false;
		}
	});

	/*google.maps.event.addListener(this.areaObj.areaPoly, 'click', function (mouseEvent) {
	if (!self.isDrawing && mouseEvent.vertex != undefined) { 
		  var path = self.areaObj.areaPoly.getPath();
		  path.removeAt(mouseEvent.vertex);
	}
	});*/
	//return {
	//    LatLng: LatLng,
	//};
};

/*
GMap.prototype.addRegion = function () {
	var polygone = createPoly();
};*/

DrawingArea.prototype.createPath = function(coords) {
	var path = [];
	for (var i = 0; i < coords.length; i++) {
		path.push(new google.maps.LatLng(coords[i].X, coords[i].Y));
	}
	return path;
};

DrawingArea.prototype.boxingGoogleCoords = function (googleCoords) {
	var selfCoords = [];
	for (var i = 0; i < googleCoords.length; i++) {
		selfCoords.push(new this.LatLng(googleCoords[i].lat(), googleCoords[i].lng()));
	}
	return selfCoords;
};

/*GMap.prototype.setCenterMarker = function (vertLatLng) {
	this.map.setCenter(vertLatLng);
	return this.placeMarker(vertLatLng);
};

/*GMap.prototype.placeInfoMarker = function (vertLatLng, infoContent) {
	var marker = this.placeMarker(vertLatLng);
	marker.info = new google.maps.InfoWindow({
		content: infoContent
	});
	google.maps.event.addListener(marker, 'click', function () {
		marker.info.open(this.map, marker);
	});
	return marker;
};*/

/*GMap.prototype.addMarker = function(markerId) {
	
	var marker = new google.maps.Marker({
		map: this.map,
		animation: google.maps.Animation.DROP,
		draggable: false
	});
	marker.setVisible(false);
	marker.info = new google.maps.InfoWindow({
		content: ""
	});
	google.maps.event.addListener(marker, 'click', function () {
		marker.info.open(this.map, marker);
	});
	this.carMarkers[markerId] = marker;
};*/


DrawingArea.prototype.startDrawing = function () {
	if (!this.isDrawing) {
		this.isDrawing = true;
		var self = this;
		var timeout = null;
	
		this.setMapCursor('crosshair');
		//this.map.setOptions({ disableDoubleClickZoom: true});
		this.areaObj.areaPoly.setOptions({ strokeWeight: 0, editable: true});
		this.stPoint = null;
		  
		this.eventListeners["map_click"] = google.maps.event.addListener(this.map, 'click', function (mouseEvent) {
			//timeout = setTimeout( function () {
			self.addAreaVertex(mouseEvent.latLng);
			self.stPoint = mouseEvent.latLng;
			//}, 200);
		});
		this.eventListeners["map_dblclick"] = google.maps.event.addListener(this.map, 'dblclick', function (mouseEvent) {
			/*mouseEvent.stop();
			clearTimeout(timeout); 
			self.addAreaVertex(mouseEvent.latLng);
			self.endDrawing();
			var center = self.map.getCenter();
			google.maps.event.addListenerOnce(self.map, 'center_changed', function () {
			var zoom = self.map.getZoom();
			zoom--;
			self.map.setZoom( zoom );	   
			self.map.setCenter( center );		      
			});		    
			return false;*/
		});
		this.eventListeners["map_rightclick"] = google.maps.event.addListener(this.map, 'rightclick', function (mouseEvent) {
			//self.startOverArea();
			//self.addAreaVertex(mouseEvent.latLng);
			self.endDrawing();
		});
		this.eventListeners["map_mousemove"] = google.maps.event.addListener(this.map, 'mousemove', function (mouseEvent) {
			if (self.stPoint) {
				self.updateDottedLine(self.stPoint, mouseEvent.latLng);
			}
		});	
	
		if (this.areaObj.dottedLine) {
			this.eventListeners["dotted_click"] = google.maps.event.addListener(this.areaObj.dottedLine, 'click', function (mouseEvent) {
			google.maps.event.trigger(self.map, 'click', mouseEvent);
			});
			this.eventListeners["dotted_dblclick"] = google.maps.event.addListener(this.areaObj.dottedLine, 'dblclick', function (mouseEvent) {
			google.maps.event.trigger(self.map, 'dblclick', mouseEvent);
			});
			this.eventListeners["dotted_rightclick"] = google.maps.event.addListener(this.areaObj.dottedLine, 'rightclick', function (mouseEvent) {
			google.maps.event.trigger(self.map, 'rightclick', mouseEvent);
			});	
		}
	}
};

DrawingArea.prototype.endDrawing = function () {
	if (this.isDrawing) {
	this.isDrawing = false;
	this.setMapCursor('default');
	this.stPoint = null;
	
	google.maps.event.removeListener(this.eventListeners["map_click"]);
	google.maps.event.removeListener(this.eventListeners["map_dblclick"]);
	google.maps.event.removeListener(this.eventListeners["map_rightclick"]);
	google.maps.event.removeListener(this.eventListeners["map_mousemove"]);
	
	if (this.areaObj.dottedLine) {
		google.maps.event.removeListener(this.eventListeners["dotted_click"]);
		google.maps.event.removeListener(this.eventListeners["dotted_dblclick"]);
		google.maps.event.removeListener(this.eventListeners["dotted_rightclick"]);
	};
	
	this.clearOverlays(["border", "dotted", "markers"]);
	//this.map.setOptions({ disableDoubleClickZoom: false});
	this.areaObj.areaPoly.setOptions({ strokeWeight: 2 });
		//this.fitArea(this.areaObj.areaPoly);
		this.fire("end_drawing");
	}
};

// Установка курсора, отображаемого при наведении на карту.
DrawingArea.prototype.setMapCursor = function (cursor) {
	this.map.setOptions({ draggableCursor: cursor });    
};


DrawingArea.prototype.showAreaOnMap = function(path) {
	this.areaObj.areaPoly.setOptions({ strokeWeight: 2, editable: false });
	this.areaObj.areaPoly.setPath(path);
};
DrawingArea.prototype.hideAreasOnMap = function (path) {
	this.areaObj.areaPoly.setPath([]);
};

// Добавление новой вершины в область.
DrawingArea.prototype.addAreaVertex = function (vertLatLng) {
	if (this.isAdding) {
		//this.stVert = vertLatLng;
		
	if (this.areaObj.areaPoly) {
		var areaPath = this.areaObj.areaPoly.getPath();
		areaPath.push(vertLatLng);
	};
	
	/*if (this.areaObj.dottedLine) {
		var dottedPath = this.areaObj.dottedLine.getPath();
		if (dottedPath.length >= 2) {
		this.areaObj.dottedLine.setPath([]);
		} else {
		dottedPath.push(vertLatLng);
		}
	};*/
		
		if (this.areaObj.borderLine) {
		var borderPath = this.areaObj.borderLine.getPath();
		borderPath.push(vertLatLng);
	};
	
	if (this.areaObj.markerList) {
		var marker = this.placeMarker(vertLatLng);
		this.areaObj.markerList.push(marker);
	};        
	};
};

DrawingArea.prototype.updateDottedLine = function(stPoint, endPoint) {
	if (this.isAdding) {
		//if (this.stVert) {
		if (this.areaObj.dottedLine) {

			this.areaObj.dottedLine.setPath([]);
			var dottedPath = this.areaObj.dottedLine.getPath();
			//dottedPath.length = 0;
			//if (dottedPath.length == 2) {
			//    dottedPath.pop();
			//    dottedPath.pop();
			dottedPath.push(stPoint);
			//};
			dottedPath.push(endPoint);
		}
		//}
	}
};

DrawingArea.prototype.clearOverlays = function (clearList) {
	if (~clearList.indexOf("border") && this.areaObj.borderLine) {
	this.areaObj.borderLine.setPath([]);
	}
	if (~clearList.indexOf("dotted") && this.areaObj.dottedLine) {
	this.areaObj.dottedLine.setPath([]);
	}
	if (~clearList.indexOf("area") && this.areaObj.areaPoly) {
	this.areaObj.areaPoly.setPath([]);
	}
	if (~clearList.indexOf("markers") && this.areaObj.markerList) {
	for (var i = 0; i < this.areaObj.markerList.length; i++) {
		this.areaObj.markerList[i].setMap(null);
	}
	this.areaObj.markerList.length = 0;
	}
};

// Разрешение на добавление области.
DrawingArea.prototype.enableAdding = function () {
	if (!this.isAdding) {
	this.isAdding = true;
	this.startDrawing();
	};
};

// Отмена добавления области.
DrawingArea.prototype.disableAdding = function () {
	if (this.isAdding) {
	this.clearOverlays(["area", "border", "dotted", "markers"]);
	this.isAdding = false;
	this.endDrawing();    
	};
};

// Сохранение добавленной области.
DrawingArea.prototype.saveArea = function() {
	if (this.areaPoly) {
		this.areaList.push(this.currPoly);
		this.currPoly = this.createPoly();
	}
};

// Начать заново добавление области.
DrawingArea.prototype.startOverArea = function() {
	if (this.isAdding) {
		this.clearOverlays(["area", "border", "dotted", "markers"]);
		if (!this.isDrawing) {
			this.startDrawing();
		} else {
			this.endDrawing();
			this.startDrawing();
		}
	}
};

// Создание маркера с анимацией.
DrawingArea.prototype.placeMarker = function (latLng) {
	var marker = new google.maps.Marker({
		position: latLng,
		map: this.map,
		animation: google.maps.Animation.DROP,
		draggable: false
	});
	return marker;
};

// Показ выбранной области на всю карту.
DrawingArea.prototype.fitArea = function(area) {
	var path = area.getPath();
	var latDown = path.getAt(0).lat();
	var latUp = latDown;
	var lngLeft = path.getAt(0).lng();
	var lngRight = lngLeft;
	for (var i = 0; i < path.length; i++) {
		var latlng = path.getAt(i);
		if (latlng.lat() < latDown) {
			latDown = latlng.lat();
		} else if (latlng.lat() > latUp) {
			latUp = latlng.lat();
		}
		if (latlng.lng() < lngLeft) {
			lngLeft = latlng.lng();
		} else if (latlng.lng() > lngRight) {
			lngRight = latlng.lng();
		}
	}

	var bounds = new google.maps.LatLngBounds(
		new google.maps.LatLng(latDown, lngLeft),
		new google.maps.LatLng(latUp, lngRight));

	this.map.fitBounds(bounds);
};

// Создание полигона.
DrawingArea.prototype.createPolygon = function() {
	var polygon = new google.maps.Polygon({
		map: this.map,
		strokeColor: "00FF00",
		strokeWeight: 0,
		strokeOpacity: 0.8,
		editable: true,
		fillColor: "00FF00",
		zIndex: 10,
	});
	return polygon;
};

// Создание полигона.
DrawingArea.prototype.createPolyline = function () {
	var polyline = new google.maps.Polyline({
		map: this.map,
		strokeColor: "00FF00",
		strokeWeight: 2,
		strokeOpacity: 0.8,
		zindex: 10,
		//editable: false,
		//fillColor: "00FF00"
	});
	return polyline;
};

// Создание полигона.
DrawingArea.prototype.createDottedLine = function () {
	var lineSymbol = {
		path: 'M -.25,-.25 .25,-.25, .25,.25 -.25,.25',
		fillOpacity: 1,
		fillColor: 'blue'
	};
	dotted = new google.maps.Polyline({
		strokeOpacity: 0.0,
		icons: [{
			icon: lineSymbol,
			repeat: '6px'
		}],
		map: this.map,
		zIndex: 20,
	});
	return dotted;
};


